﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;

using iPdf.Properties;
using iTextSharp.text.pdf;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Forms;


namespace iPdf
{
    partial class Previewer : UserControl
    {
        #region Fields
        PdfPageInformer pageInformer ;
        bool pageNoBoxInitializing = true;

        private int currentPageNo = 1;
        #endregion

        #region Properties

        public int CurrentPageNo
        {
            get
            {
                return currentPageNo;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.Parse(System.String)")]
        private int PageNo
        {
            get
            {
                if (string.IsNullOrEmpty( this.PageNoBox.Text ) )
                {
                    return 0;
                }
                return int.Parse(this.PageNoBox.Text);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly")]
        public PdfPageInformer PageInformer
        {
            get
            {
                return pageInformer;
            }
            set
            {
                pageInformer = value;
            }
        }
        

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.Parse(System.String)")]
        protected int NumberOfPages
        {
            get
            {
                return pageInformer.NumberOfPages;
            }
        }

        public bool Busy
        {
            get
            {
                return this.Visible;
            }
        }

        public PagePreview.RenderEvent RenderEvent
        {
            get { return this.renderEvent; }
            set
            {
                this.PageViewer.SetRenderEvent(value);
                this.renderEvent = value;
            }
        }
        PagePreview.RenderEvent renderEvent;

        #endregion

        #region Ctor
        public Previewer()
        {
            InitializeComponent();
        }
        #endregion

        #region Methods
        
        #region Events handlers

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")]
        protected override void  OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (Elegant.Ui.Control.IsInDesignMode)
            {
                return;
            }

            if (this.Visible)
            {
                pageNoBoxInitializing = true;
                string format = "/{0:D4}";
                if (this.pageInformer != null && this.pageInformer.IsValid)
                {
                    NumberOfPagesLabel.Text = string.Format(format, 
                        this.pageInformer.NumberOfPages);
                    
                    int from = 1;
                    if (Global.CurrentPage.IsColumnVisible(Global.Grid.From))
                    {
                         from = (int) Global.Grid.From.GetValueAt(Global.Grid.SingleSelectedRowId);
                    }

                    PageNoBox.Text = from.ToString();
                    PageNoBox.Enabled = true;
                    PageNoBox.MaxLength = NumberOfPages.ToString().Length;

                    currentPageNo = from;
                }
                else
                {
                    NumberOfPagesLabel.Text = string.Format(format, 0);
                    PageNoBox.Text = "0";
                    PageNoBox.Enabled = false;
                }

                UpdatePreviewer();
                pageNoBoxInitializing = false;
            }
            else
            {
                Global.MainWindow.ShowPageSize(0.0f, 0.0f);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
        private void PreviousPage_Click(object sender, EventArgs e)
        {
            this.PageNoBox.Text = (PageNo - 1).ToString();

            UpdatePreviewer();
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
        private void NextPage_Click(object sender, EventArgs e)
        {
            this.PageNoBox.Text = (PageNo + 1).ToString();

            UpdatePreviewer();
        }

        private void PageNoBox_TextChanged(object sender, EventArgs e)
        {
            if (pageNoBoxInitializing)
            {
                return;
            }

            if (!IsValidPageNo(PageNoBox.Text))
            {
                PageNoBox.ShowBalloon(Resources.BadPageNo);
                WinApi.MessageBeep(0);
            }

            UpdatePreviewer();
        }

        private void PageNoBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            char keyCh = e.KeyChar;
            if ( !char.IsDigit(keyCh)  && keyCh != '\b' && 
                 (ModifierKeys & (Keys.Alt | Keys.Control)) == Keys.None)
            {
                e.Handled = true;
                WinApi.MessageBeep(0);
            }
        }

        private void ZoomIn_Click(object sender, EventArgs e)
        {
            this.PageViewer.ZoomPercent = GetNewZoom(this.PageViewer.ZoomPercent, true);

            UpdateZoomButtons();
        }

        private void ZoomOut_Click(object sender, EventArgs e)
        {
            this.PageViewer.ZoomPercent = GetNewZoom(this.PageViewer.ZoomPercent, false);

            UpdateZoomButtons();
        }

        private void FitToScreen_Click(object sender, EventArgs e)
        {
            this.PageViewer.Zoom = Zoom.FullPage;
        }
        #endregion

        private int GetNewZoom(int currentZoom, bool larger)
        {
            int[] values = new int[]
              {
                10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 
                250, 300, 350, 400, 450, 500, 600, 700, 800
              };

            if (currentZoom <= (int)Zoom.Mininum && !larger)
                return (int)Zoom.Mininum;
            else if (currentZoom >= (int)Zoom.Maximum && larger)
                return (int)Zoom.Maximum;

            if (larger)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    if (currentZoom < values[i])
                        return values[i];
                }
            }
            else
            {
                for (int i = values.Length - 1; i >= 0; i--)
                {
                    if (currentZoom > values[i])
                        return values[i];
                }
            }

            return (int)Zoom.Percent100;
        }

        public void UpdatePreviewer()
        {
            if (this.Visible == false)
            {
                return;
            }

            bool isLegalPageNo = PageNo >= 1 && PageNo <= NumberOfPages;
            this.PreviousPage.Enabled = isLegalPageNo && PageNo > 1;
            this.NextPage.Enabled = isLegalPageNo && PageNo < NumberOfPages;

            if (isLegalPageNo)
            {
                RenderIthPage(PageNo);
            }

            UpdateZoomButtons();
        }

        private void RenderIthPage(int i)
        {
            iTextSharp.text.Rectangle pageRect = pageInformer.GetPageRectange(i);
            if (currentPageNo != i)
            {
                iTextSharp.text.Rectangle prevPageRect = pageInformer.GetPageRectange(currentPageNo);
                if (prevPageRect.Width == pageRect.Width &&
                    prevPageRect.Height == pageRect.Height)
                {
                    currentPageNo = i;
                    //needless to do anything
                    return;
                }
            }


            XSize pageSize = new XSize(pageRect.Width, pageRect.Height);
            if (pageSize != this.PageViewer.PageSize)
            {
                this.PageViewer.PageSize = pageSize;

                //Make sure that the ZoomChanged event is triggered so that the scroll bar will be in 
                //correct position
                this.PageViewer.Zoom = Zoom.OriginalSize;
                this.PageViewer.Zoom = Zoom.FullPage;
            }

            Global.MainWindow.ShowPageSize(pageRect.Width, pageRect.Height);

            this.PageViewer.Invalidate();

            currentPageNo = i;
        }



        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.Parse(System.String)")]
        private bool IsValidPageNo(string text)
        {
            if (!Helper.IsNumeric(text))
            {
                return false;
            }
            int pageNo = int.Parse(text);
            if (pageNo < 1 ||
                pageNo > NumberOfPages)
            {
                return false;
            }

            return true;
        }

        private void UpdateZoomButtons()
        {
            this.ZoomIn.Enabled = this.PageViewer.ZoomPercent < (int)Zoom.Maximum;
            this.ZoomOut.Enabled = this.PageViewer.ZoomPercent > (int)Zoom.Mininum;
        }

        #endregion

    }
}
